import {log} from "./utils/log";
import {XgVideo} from "./video";
import {Options, PlayStatus, XgEvents} from "./types";
import {classNames} from "./consts";
import {XgPosterBtn} from "./poster-btn";
import mitt from 'mitt';
import {$} from "./utils/dom";
import {XgControls} from "./controls";

import './styles/index.css';

const defaultOptions: Options = {
  src: '',
  controls: false,
  poster: '',
  preload: 'metadata',
  autoplay: true,
  posterEl: '',
  resources: [],
  barrage: [],
}

export class XgPlayer {
  container!: HTMLElement;
  config = defaultOptions;
  videoInstance!: XgVideo;
  posterBtnInstance!: XgPosterBtn;
  controlsInstance!: XgControls;
  // @ts-ignore
  emitter = mitt<XgEvents>();
  mouseenter = false;
  playStatus = new Proxy<PlayStatus>({
    playing: false
  }, {
    set: (target, attr: keyof PlayStatus, value): boolean => {
      if (attr === 'playing') {
        if (target.playing !== value) {
          this.watchPlaying(value);
        }
      }
      target[attr] = value;
      return true;
    }
  });
  constructor(el: string | HTMLElement, options?: Partial<Options>) {
    const container = $(el);
    if (container) {
      container.classList.add(classNames.root);
      this.container = container;
      Object.assign(this.config, options);
      this.init();
    } else {
      log('请传入el容器', 'error');
    }
  }
  private init() {
    this.videoInstance = new XgVideo(this);
    if (this.config.poster) {
      this.posterBtnInstance = new XgPosterBtn(this);
    }
    this.controlsInstance = new XgControls(this);
    this.container.addEventListener('mouseenter', this.handleHover.bind(this));
    this.container.addEventListener('mouseleave', this.handleHover.bind(this));
    this.emitter.on('play', this.handlePlay.bind(this));
    this.emitter.on('togglePlay', this.handleTogglePlay.bind(this));
    this.emitter.on('playing', this.handlePlaying.bind(this));
    this.emitter.on('pause', this.handlePause.bind(this));
    this.emitter.on('ended', this.handleEnded.bind(this));
    this.emitter.on('error', this.handleError.bind(this));
    this.emitter.on('resourceChange', this.handleResourceChange.bind(this));
    this.emitter.on('timeupdate', this.handleTimeUpdate.bind(this));
  }
  handleHover(event: MouseEvent) {
    this.mouseenter = event.type === 'mouseenter';
    this.controlsInstance.toggleShow(this.mouseenter);
  }
  handleTimeUpdate(time: number) {
    if (time > 3 && !this.mouseenter) {
      this.controlsInstance.toggleShow(false);
    }
  }
  handlePlay() {
    console.log('handlePlay');
    this.videoInstance.play();
  }
  handleTogglePlay() {
    if (this.playStatus.playing) {
      this.videoInstance.pause();
    } else {
      this.handlePlay();
    }
  }
  handlePlaying() {
    console.log('handlePlaying');
    this.changePlaying(true);
  }
  handlePause() { // 播放结束也会触发
    console.log('handlePause');
    this.changePlaying(false);
  }
  handleEnded() {
    console.log('handleEnded');
    this.changePlaying(false);
  }
  handleError() {
    this.changePlaying(false);
    log('播放失败', 'error');
  }
  changePlaying(playing: boolean) {
    console.log('changePlaying', playing);
    if (this.playStatus.playing !== playing) {
      this.playStatus.playing = playing;
    }
  }
  handleResourceChange(url: string) {
    this.videoInstance.changeResource(url);
  }
  watchPlaying(newValue: boolean) {
    // console.log('watchPlaying', newValue);
    this.posterBtnInstance?.toggle(newValue ? 'none' : 'block');
    this.emitter.emit('playingChange', newValue);
  }
  destory() {
    this.emitter.all.clear();
  }
}
